package com.nseeod.gui;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JProgressBar;
import javax.swing.table.AbstractTableModel;

import com.nseeod.download.Download;

// This class manages the download table's data.
class DownloadsTableModel extends AbstractTableModel implements Observer {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1656683418638125584L;

	// These are the names for the table's columns.
	private static final String[] columnNames = { "URL", "Size", "Progress",
			"Status" };

	// These are the classes for each column's values.
	private static final Class[] columnClasses = { String.class, String.class,
			JProgressBar.class, String.class };

	// The table's list of downloads.
	private ArrayList<Download> downloadList = new ArrayList<Download>();

	// private PriorityQueue<Download> downloadQueue = new
	// PriorityQueue<Download>();
	// Add a new download to the table.
	public void addDownload(Download download) {

		// Register to be notified when the download changes.
		download.addObserver(this);

		downloadList.add(download);
		// downloadQueue.offer(download);

		// Fire table row insertion notification to table.
		fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
	}

	// Get a download for the specified row.
	public Download getDownload(int row) {
		return (Download) downloadList.get(row);
	}

	// Remove a download from the list.
	public void clearDownload(int row) {
		downloadList.remove(row);

		// Fire table row deletion notification to table.
		fireTableRowsDeleted(row, row);
	}
	// Remove a download from the list.
	public void clearAllDownload() {
		int size =downloadList.size();
		if(size>1)
		{	
		downloadList = new ArrayList<Download>();
		// Fire table row deletion notification to table.
		fireTableRowsDeleted(0, size-1);
		}
	}
	// Get table's column count.
	public int getColumnCount() {
		return columnNames.length;
	}

	// Get a column's name.
	public String getColumnName(int col) {
		return columnNames[col];
	}

	// Get a column's class.
	public Class getColumnClass(int col) {
		return columnClasses[col];
	}

	// Get table's row count.
	public int getRowCount() {
		return downloadList.size();
	}

	// Get value for a specific row and column combination.
	public Object getValueAt(int row, int col) {

		Download download = (Download) downloadList.get(row);
		switch (col) {
		case 0: // URL
			return download.getUrl();
		case 1: // Size
			int size = (int)download.getSize();
			return (size == -1) ? "" : Integer.toString(size);
		case 2: // Progress
			return new Float(download.getProgress());
		case 3: // Status
			return Download.STATUSES[download.getStatus()];
		}
		return "";
	}

	/*
	 * Update is called when a Download notifies its observers of any changes
	 */
	public synchronized void update(Observable o, Object arg) {
		if (o instanceof Download) {
			int index = downloadList.indexOf(o);
			int size = downloadList.size();
			if (index < size - 1 && ((Download) o).getStatus() != Download.IMPORTED  && ((Download) o).getStatus() != Download.IMPERROR
					&& ((Download) o).getStatus() != Download.DOWNLOADING  && ((Download) o).getPrevStatus() != Download.ERROR ){
				int i = index;
				Download nextDownload;
				do {
					nextDownload = downloadList.get(++i);

				} while (i < size - 1
						&& nextDownload.getStatus() != Download.READY);
				if (nextDownload.getStatus() == Download.READY)
					nextDownload.start();
			}
			// Fire table row update notification to table.
			fireTableRowsUpdated(index, index);
		}
	}
}